package com.zzzy.cont.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhuozhengsoft.pageoffice.OpenModeType;
import com.zhuozhengsoft.pageoffice.word.DataRegionWriter;
import com.zhuozhengsoft.pageoffice.word.WordDocumentWriter;
import com.zzzy.common.enums.YesOrNoEnum;
import com.zzzy.common.exception.WarningException;
import com.zzzy.common.util.AssertUtil;
import com.zzzy.common.util.CglibBeanCopierUtil;
import com.zzzy.common.util.FileUtil;
import com.zzzy.cont.common.enums.ConStatusEnum;
import com.zzzy.cont.dao.entity.ConFile;
import com.zzzy.cont.dao.entity.Contract;
import com.zzzy.cont.dao.mapper.ContractMapper;
import com.zzzy.cont.dto.DataRegionDto;
import com.zzzy.cont.vo.contract.my.ConBasicInfoRes;
import com.zzzy.cont.vo.contract.my.ConInfoRes;
import com.zzzy.cont.vo.pageoffice.OpenOfficeFileRes;
import com.zzzy.framework.common.enums.sys.DataScopeEnum;
import com.zzzy.framework.common.util.PageOfficeUtil;
import com.zzzy.framework.common.util.SecurityUtils;
import com.zzzy.framework.dto.DataPermissionDto;
import com.zzzy.sys.api.UserApi;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Objects;
import java.util.Set;

/**
 * 合同基本信息 服务实现类
 *
 * @author fc
 * @since 2024-05-27
 */
@Service
public class ConService extends ServiceImpl<ContractMapper, Contract> {

    @Resource
    protected ConFileService conFileService;
    @Resource
    protected ConActivityNoteService conActivityNoteService;
    @Resource
    protected ConUserOperateLinkService conUserOperateLinkService;
    @Resource
    protected UserApi userService;

    public Contract getConById(Long id) {
        Contract contract = getById(id);
        AssertUtil.nonNull(contract, "合同不存在");
        return contract;
    }

    public Contract getConByIdForQuery(Long id) {
        Contract contract = getConById(id);
        DataPermissionDto dataPermissionDto = SecurityUtils.getLoginUser().getDataPermissionDto();
        Long loginUserId = SecurityUtils.getLoginUser().getId();
        //当前用户为起草人或当前办理人
        if (loginUserId.equals(contract.getUserId()) || loginUserId.equals(contract.getOperatorId())){
            return contract;
        }
        //当前用户为全部数据权限
        if (DataScopeEnum.ALL.getValue().equals(dataPermissionDto.getDataPermission())){
            return contract;
        }
        Set<Long> userIdSet = dataPermissionDto.getUserIdSet();
        //当前用户下属用户(包含自己) 为合同起草人/当前办理人/经办人
        if (userIdSet.contains(contract.getUserId())
                || userIdSet.contains(contract.getOperatorId())
                || conUserOperateLinkService.isContainsLink(id, userIdSet)){
            return contract;
        }
        throw new WarningException("当前用户无此合同查看权限");
    }

    public void validateAuthForQuery(Long id) {
        getConByIdForQuery(id);
    }

    public Contract getConByIdForUpdate(Long id) {
        Contract contract = getConByIdForOperate(id);
        Long loginUserId = SecurityUtils.getLoginUser().getId();
        AssertUtil.isEquals(loginUserId, contract.getUserId(), "当前用户无此合同修改权限");
        AssertUtil.isEquals(loginUserId, contract.getOperatorId(), "当前用户无此合同修改权限");
        return contract;
    }

    public Contract getConByIdForOperate(Long id) {
        Contract contract = getConById(id);
        Long loginUserId = SecurityUtils.getLoginUser().getId();
        AssertUtil.isEquals(loginUserId, contract.getOperatorId(), "当前用户无此合同操作权限");
        return contract;
    }

    public ConBasicInfoRes getConBasicInfo(Long id) {
        validateAuthForQuery(id);
        Contract contract = getConById(id);
        ConFile conFile = conFileService.getConFileByConId(id);
        ConInfoRes conInfo = CglibBeanCopierUtil.copy(conFile, ConInfoRes.class);
        CglibBeanCopierUtil.copy(contract, conInfo);
        return conInfo;
    }


    public ConInfoRes getConInfo(Long id) {
        validateAuthForQuery(id);
        Contract contract = getConById(id);
        ConFile conFile = conFileService.getConFileByConId(id);
        ConInfoRes conInfo = CglibBeanCopierUtil.copy(conFile, ConInfoRes.class);
        CglibBeanCopierUtil.copy(contract, conInfo);
        return conInfo;
    }
    public OpenOfficeFileRes getOpenOfficeResByConId(Long id, String openFileUrl) {
        validateAuthForQuery(id);
        ConInfoRes conInfo = getConInfo(id);
        //是否当前可操作人
        boolean isCurrentOperator = conInfo.getOperatorId().equals(SecurityUtils.getLoginUser().getId());
        //如果不是当前操作人则只读
        if (!isCurrentOperator){
            return getReadOnlyPageOfficeRes(openFileUrl, id);
        }

        boolean isDraft = ConStatusEnum.DRAFT.getValue().equals(conInfo.getStatus());
        boolean isAudit = ConStatusEnum.AUDIT.getValue().equals(conInfo.getStatus());
        boolean isSign = ConStatusEnum.SIGN.getValue().equals(conInfo.getStatus());
        boolean isArchiving = ConStatusEnum.ARCHIVING.getValue().equals(conInfo.getStatus());

        String pdfFileName = conInfo.getName() +(YesOrNoEnum.YES.getValue().equals(conInfo.getIsFixedFormat()) ? "-固定格式" : "-非固定格式") + "." + FileUtil.PDF;
        //起草或审核中
        if (isDraft || isAudit){
            //若有pdf文件则说明用户上传的为pdf
            if (Objects.nonNull(conInfo.getPdfFileBlob())){
                String pdfReadOnlyHtml = PageOfficeUtil.getPdfHtml(openFileUrl, pdfFileName);
                return OpenOfficeFileRes.builder().html(pdfReadOnlyHtml).pdf(true).build();
            } else {
                String wordFileName = conInfo.getName() +(YesOrNoEnum.YES.getValue().equals(conInfo.getIsFixedFormat()) ? "-固定格式" : "-非固定格式")
                        + "." + FileUtil.getFileType(conInfo.getWordFileBlob());
                String wordHtml;
                if (YesOrNoEnum.YES.getValue().equals(conInfo.getIsFixedFormat())) {
                    WordDocumentWriter doc = new WordDocumentWriter();
                    if (!CollectionUtils.isEmpty(conInfo.getDataRegions())){
                        DataRegionWriter dataRegion;
                        for (DataRegionDto region : conInfo.getDataRegions()) {
                            dataRegion = doc.openDataRegion(region.getName());
                            dataRegion.setEditing(true);
                            dataRegion.setSubmitAsFile(true);
                        }
                    }
                    wordHtml = PageOfficeUtil.getWordHtml(openFileUrl, wordFileName, OpenModeType.docSubmitForm, doc);
                } else {
                    wordHtml = PageOfficeUtil.getWordHtml(openFileUrl, wordFileName, OpenModeType.docAdmin);
                }
                return OpenOfficeFileRes.builder().html(wordHtml).edit(true).build();
            }
        } else if (isSign){
            String pdfHtml = PageOfficeUtil.getPdfHtml(openFileUrl, pdfFileName);
            return OpenOfficeFileRes.builder().html(pdfHtml).pdf(true).edit(true).build();
        } else if (isArchiving){
            String pdfReadOnlyHtml = PageOfficeUtil.getPdfHtml(openFileUrl, pdfFileName);
            return OpenOfficeFileRes.builder().html(pdfReadOnlyHtml).pdf(true).build();
        } else {
            return getReadOnlyPageOfficeRes(openFileUrl, id);
        }
    }

    private OpenOfficeFileRes getReadOnlyPageOfficeRes(String openFileUrl, Long conId) {
        ConInfoRes docInfo = getConInfo(conId);
        if (Objects.nonNull(docInfo.getPdfFileBlob())){
            String fileName = docInfo.getName() +(YesOrNoEnum.YES.getValue().equals(docInfo.getIsFixedFormat()) ? "-固定格式" : "-非固定格式") + "." + FileUtil.PDF;
            String pdfReadOnlyHtml = PageOfficeUtil.getPdfHtml(openFileUrl, fileName);
            return OpenOfficeFileRes.builder().html(pdfReadOnlyHtml).pdf(true).build();
        } else {
            String fileName = docInfo.getName() +(YesOrNoEnum.YES.getValue().equals(docInfo.getIsFixedFormat()) ? "-固定格式" : "-非固定格式")
                    + "." + FileUtil.getFileType(docInfo.getWordFileBlob());
            String wordHtml = PageOfficeUtil.getWordHtml(openFileUrl, fileName, OpenModeType.docReadOnly);
            return OpenOfficeFileRes.builder().html(wordHtml).build();
        }
    }
}
